package cn.fancylab.template.web.action;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.jivesoftware.smack.packet.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import com.eboo.openfire.cmd.sub.GatewayLockerOpen;
import com.eboo.openfire.vo.UploadData;

import cn.fancylab.model.bs.DeviceCabinetBox;
import cn.fancylab.model.bs.DeviceController;
import cn.fancylab.model.bs.DeviceGateway;
import cn.fancylab.model.bs.GatewayRunLog;
import cn.fancylab.model.bs.ShoppingCart;
import cn.fancylab.model.bs.ShoppingCartDetail;
import cn.fancylab.model.bs.StockGoods;
import cn.fancylab.template.Keys;
import cn.fancylab.template.service.BaseAppService;
import cn.fancylab.template.service.DeviceControllerService;
import cn.fancylab.template.untrans.OpenFireService;
import cn.fancylab.template.util.ByteUtil;
import cn.fancylab.template.util.HttpUtil;
import cn.fancylab.template.util.JsonUtil;
import cn.fancylab.template.vo.ResultCode;
import cn.fancylab.untrans.JmsService;
import cn.fancylab.web.support.FancyVelocityView;
import cn.fancylab.web.support.JsonStrDirectOut;

@Controller
public class ApiDeviceController extends AnnotationController {

	@Autowired
	@Qualifier("deviceControllerService")
	protected DeviceControllerService deviceControllerService;

	@Autowired
	@Qualifier("baseAppService")
	private BaseAppService baseAppService;

	@Autowired
	@Qualifier("openFireService")
	private OpenFireService openFireService;

	@Autowired
	@Qualifier("monitorJmsService")
	private JmsService jmsService;

	private String shopAppUrl = "https://quick.neishou.net/service/";

	/**
	 * 扫码开门请求
	 * <p>
	 * 1、小程序开启二维码扫码
	 * </p>
	 * <p>
	 * 2、由小程序发出开门请求，同时用户必须是登录状态
	 * </p>
	 * 
	 * @param device_serialno
	 * @param gate_serialno
	 * @param custom_id
	 * @return
	 */
	@GetMapping("/api/opendoor.xhtml")
	public String opendoor(String device_serialno, String gate_serialno, String custom_id, Integer type) {
		ResultCode resultCode = new ResultCode();
		if (StringUtils.isNotBlank(device_serialno)) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("identified_no", device_serialno);
			map.put("is_del", 0);
			DeviceController deviceController = baseAppService.getObjectByProperty(DeviceController.class, map);

			if (StringUtils.isNotBlank(gate_serialno)) {
				map = new HashMap<String, Object>();
				map.put("identified_no", gate_serialno);
				map.put("is_del", 0);
				DeviceGateway deviceGateway = baseAppService.getObjectByProperty(DeviceGateway.class, map);

				GatewayLockerOpen GatewayLockerOpen = new GatewayLockerOpen();
				GatewayLockerOpen.setBusinessType((byte) 1);
				GatewayLockerOpen.setControllerIdentifiedNo(deviceController.getIdentified_no());
				GatewayLockerOpen.setGatewayIdentifiedNo(deviceGateway.getIdentified_no());

				openFireService.sendMessage(deviceController.getOpenfire_username(),
						JsonUtil.serialize(GatewayLockerOpen), UUID.randomUUID().toString(), (Message message) -> {
							return null;
						});

				resultCode.setResultflag(true);
				resultCode.setResultMsg("开门成功！");
			}
		}

		HttpServletRequest request = getRequest();
		request.setAttribute(FancyVelocityView.RENDER_JSON, "true");
		request.setAttribute(FancyVelocityView.DIRECT_OUTPUT,
				new JsonStrDirectOut(getResponse(), JsonUtil.serialize(resultCode)));
		return "common/directOut.vm";
	}

	/**
	 * 建立购物车
	 * <p>
	 * 1、扫码开门后，有中控发出请求，建立购物车
	 * </p>
	 * 
	 * @param device_serialno
	 * @param gate_serialno
	 * @param custom_id
	 * @return
	 */
	@GetMapping("/api/shoppingcart.xhtml")
	@ResponseBody
	public String shoppingcart(String device_serialno, String gate_serialno, String custom_id, Integer type) {
		ResultCode resultCode = new ResultCode();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("device_serialno", device_serialno);
		map.put("gate_serialno", gate_serialno);
		map.put("is_finish", 0);
		map.put("is_del", 0);
		int count = baseAppService.getObjectCountByProperty(ShoppingCart.class, map);
		if (count > 0) {
			resultCode.setResultflag(false);
			resultCode.setResultMsg("本次购物车创建失败，有未完成的购物请求！");
		} else {
			ShoppingCart shoppingCart = new ShoppingCart();
			shoppingCart.setUuid(UUID.randomUUID().toString());
			shoppingCart.setCustom_id(Long.valueOf(custom_id));
			shoppingCart.setDevice_serialno(device_serialno);
			shoppingCart.setGate_serialno(gate_serialno);
			shoppingCart.setAdd_date(new Date());
			shoppingCart.setIs_del(Keys.IsDel.NOT_DEL.getIndex());
			shoppingCart.setIs_finish(Keys.IsFinish.NOT_FINISH.getIndex());
			baseAppService.saveObject(shoppingCart);

			resultCode.setResultflag(true);
			resultCode.setResultMsg("本次购物车创建成功！");
		}

		HttpServletRequest request = getRequest();
		request.setAttribute(FancyVelocityView.RENDER_JSON, "true");
		request.setAttribute(FancyVelocityView.DIRECT_OUTPUT,
				new JsonStrDirectOut(getResponse(), JsonUtil.serialize(resultCode)));
		return "common/directOut.vm";
	}

	/**
	 * 结算
	 * <p>
	 * 1、在关门后，有中控发出请求，进行结算，同时发送隔间板重量信息
	 * </p>
	 * 
	 * @param device_serialno
	 * @param gate_serialno
	 * @param custom_id
	 * @return
	 */
	@PostMapping("/api/settleaccounts.xhtml")
	@ResponseBody
	public String settleaccounts(String device_serialno, String gate_serialno, String custom_id, Integer type) {
		ResultCode resultCode = new ResultCode();

		// 关门后发送订单信息，并结算
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("device_serialno", device_serialno);
		map.put("gate_serialno", gate_serialno);
		map.put("is_finish", 0);
		map.put("is_del", 0);
		int count = baseAppService.getObjectCountByProperty(ShoppingCart.class, map);
		if (count == 0) {
			resultCode.setResultflag(false);
			resultCode.setResultMsg("订单中购物内容！");
		} else if (count > 1) {
			resultCode.setResultflag(false);
			resultCode.setResultMsg("存在多个未完成的订单！");
		} else {
			ShoppingCart shoppingCart = baseAppService.getObjectByProperty(ShoppingCart.class, map);

			map = new HashMap<String, Object>();
			map.put("link_uuid", shoppingCart.getUuid());
			map.put("is_del", 0);
			List<ShoppingCartDetail> shoppingCartDetailList = baseAppService
					.getObjectListByProperty(ShoppingCartDetail.class, map);
			List<HashMap<String, String>> sku = new ArrayList<HashMap<String, String>>();
			HashMap<String, String> mapsku = null;
			for (ShoppingCartDetail shoppingCartDetail : shoppingCartDetailList) {
				mapsku = new HashMap<String, String>();
				mapsku.put("url", "");
				mapsku.put("id", shoppingCartDetail.getUuid());
				mapsku.put("change", shoppingCartDetail.getWeight().multiply(new BigDecimal("-1")).toString());
				mapsku.put("price", shoppingCartDetail.getPrice().setScale(2).toString());
				mapsku.put("price_type", "weight");
				mapsku.put("name", shoppingCartDetail.getGoods_name());
				sku.add(mapsku);
			}

			StringBuffer url = new StringBuffer(shopAppUrl);
			url.append("SmallProgramService.do?method=creatOrder");
			url.append("&action=SHOPPING_RESULT");

			HashMap<String, Object> responseBodyMap = new HashMap<String, Object>();
			responseBodyMap.put("fridge_id", device_serialno);
			responseBodyMap.put("user_id", custom_id);
			responseBodyMap.put("sku", mapsku);
			responseBodyMap.put("code", "SUCCESS");

			HttpResponse respone = HttpUtil.executePostMethod(url.toString(), JsonUtil.serialize(responseBodyMap),
					"utf-8");
			HttpEntity httpEntity = respone.getEntity();
			try {
				InputStream in = httpEntity.getContent();
				BufferedReader sf = new BufferedReader(new InputStreamReader(in));
				StringBuffer sb = new StringBuffer("");
				String s;
				while ((s = sf.readLine()) != null) {
					sb.append(s);
				}
				if (StringUtils.isNotBlank(sb)) {
					HashMap retrurnInfo = JsonUtil.deserialize(sb.toString(), HashMap.class);
					if ("SUCCESS".equals(retrurnInfo.get("code").toString())) {
						shoppingCart.setLink_uuid(retrurnInfo.get("out_trade_no").toString());
					}
				}
			} catch (UnsupportedOperationException | IOException e) {
				e.printStackTrace();
			}
		}

		HttpServletRequest request = getRequest();
		request.setAttribute(FancyVelocityView.RENDER_JSON, "true");
		request.setAttribute(FancyVelocityView.DIRECT_OUTPUT,
				new JsonStrDirectOut(getResponse(), JsonUtil.serialize(resultCode)));
		return "common/directOut.vm";
	}

	/**
	 * 购物内容
	 * <p>
	 * 1、定时发送购物内容信息，并计算商品重量和价格
	 * </p>
	 * 传入数据格式 uploadData
	 * 
	 * @return
	 */
	@PostMapping("/api/shoppinggoods.xhtml")
	@ResponseBody
	public String shoppinggoods(@RequestBody String param) {
		ResultCode resultCode = new ResultCode();

		HashMap<String, Object> map;

		if (StringUtils.isNotBlank(param)) {
			UploadData uploadData = JsonUtil.deserialize(param, UploadData.class);

			BigDecimal m_weight = null;
			if (StringUtils.isNotBlank(uploadData.getCmdResultData())) {
				m_weight = new BigDecimal(uploadData.getCmdResultData());
			}

			map = new HashMap<String, Object>();
			map.put("identified_no", uploadData.getControllerIdentifiedNo());
			map.put("is_del", 0);
			DeviceController deviceController = baseAppService.getObjectByProperty(DeviceController.class, map);

			map = new HashMap<String, Object>();
			map.put("identified_no", uploadData.getGatewayIdentifiedNo());
			map.put("bs_d_controller_uuid", deviceController.getUuid());
			map.put("is_del", 0);
			DeviceGateway deviceGateway = baseAppService.getObjectByProperty(DeviceGateway.class, map);

			map = new HashMap<String, Object>();
			map.put("bs_d_gateway_uuid", deviceGateway.getUuid());
			map.put("address_485", ByteUtil.toHex(uploadData.getAddr()));
			map.put("is_del", 0);
			DeviceCabinetBox deviceCabinetBox = baseAppService.getObjectByProperty(DeviceCabinetBox.class, map);

			map = new HashMap<String, Object>();
			map.put("link_uuid", uploadData.getShopping_cart_uuid());
			map.put("bs_d_cabinetbox_uuid", deviceCabinetBox.getUuid());
			map.put("is_del", 0);
			ShoppingCartDetail shoppingCartDetail = baseAppService.getObjectByProperty(ShoppingCartDetail.class, map);
			if (null != shoppingCartDetail) {
				// 隔间板重量不变不执行重新计算，直接返回。
				if (shoppingCartDetail.getM_weight().compareTo(m_weight) == 0) {
					HttpServletRequest request = getRequest();

					resultCode.setResultflag(true);

					request.setAttribute(FancyVelocityView.RENDER_JSON, "true");
					request.setAttribute(FancyVelocityView.DIRECT_OUTPUT,
							new JsonStrDirectOut(getResponse(), JsonUtil.serialize(resultCode)));
					return "common/directOut.vm";
				}
			}

			map = new HashMap<String, Object>();
			map.put("uuid", uploadData.getShopping_cart_uuid());
			map.put("is_del", 0);
			ShoppingCart shoppingCart = baseAppService.getObjectByProperty(ShoppingCart.class, map);

			if (shoppingCart != null) {
				map = new HashMap<String, Object>();
				map.put("uuid", uploadData.getShopping_cart_uuid());
				map.put("bs_d_cabinetbox_uuid", deviceCabinetBox.getUuid());
				map.put("is_del", 0);
				StockGoods stockGoods = baseAppService.getObjectByProperty(StockGoods.class, map);

				if (stockGoods != null) {
					if (null == shoppingCartDetail) {
						shoppingCartDetail = new ShoppingCartDetail();
						shoppingCartDetail.setUuid(UUID.randomUUID().toString());
						shoppingCartDetail.setLink_uuid(shoppingCart.getUuid());
						shoppingCartDetail.setBs_d_cabinetbox_uuid(deviceCabinetBox.getUuid());
						shoppingCartDetail.setGoods_uuid(stockGoods.getGoods_uuid());
						shoppingCartDetail.setGoods_name(stockGoods.getGoods_name());
						shoppingCartDetail.setAdd_date(new Date());
						shoppingCartDetail.setIs_del(Keys.IsDel.NOT_DEL.getIndex());
						shoppingCartDetail.setM_weight(m_weight);
						shoppingCartDetail.setPrice(stockGoods.getPrice());
					}
					shoppingCartDetail.setWeight(stockGoods.getWeight().subtract(m_weight));
					shoppingCartDetail.setMoney(shoppingCartDetail.getPrice().multiply(shoppingCartDetail.getWeight()));
					baseAppService.saveObject(shoppingCartDetail);
				}
			}
		}

		HttpServletRequest request = getRequest();
		request.setAttribute(FancyVelocityView.RENDER_JSON, "true");
		request.setAttribute(FancyVelocityView.DIRECT_OUTPUT,
				new JsonStrDirectOut(getResponse(), JsonUtil.serialize(resultCode)));
		return "common/directOut.vm";
	}

	/**
	 * 隔间列表
	 * <p>
	 * 隔间列表
	 * </p>
	 * 
	 * @param device_serialno
	 * @param gate_serialno
	 * @param custom_id
	 * @return
	 */
	@GetMapping("/api/listcabinetbox.xhtml")
	public String listDeviceCabinetBox(String device_serialno, String gate_serialno) {
		List<DeviceCabinetBox> deviceCabinetBoxList = null;

		if (StringUtils.isNotBlank(device_serialno)) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("identified_no", device_serialno);
			map.put("is_del", 0);
			DeviceController deviceController = baseAppService.getObjectByProperty(DeviceController.class, map);

			if (null != deviceController && StringUtils.isNotBlank(gate_serialno)) {
				map = new HashMap<String, Object>();
				map.put("bs_d_controller_uuid", deviceController.getUuid());
				map.put("identified_no", gate_serialno);
				map.put("is_del", 0);
				DeviceGateway deviceGateway = baseAppService.getObjectByProperty(DeviceGateway.class, map);
				if (deviceGateway != null) {
					map = new HashMap<String, Object>();
					map.put("bs_d_gateway_uuid", deviceGateway.getUuid());
					map.put("is_del", 0);
					deviceCabinetBoxList = baseAppService.getObjectListByProperty(DeviceCabinetBox.class, map);
				}
			}
		}
		HttpServletRequest request = getRequest();
		request.setAttribute(FancyVelocityView.RENDER_JSON, "true");
		request.setAttribute(FancyVelocityView.DIRECT_OUTPUT,
				new JsonStrDirectOut(getResponse(), JsonUtil.serialize(deviceCabinetBoxList)));
		return "common/directOut.vm";
	}

	/**
	 * 锁状态door_lock:on ; led灯led:on ; 中控device_serialno ; 网关板gate_serialno ; 客户ID：custom_id
	 * 
	 * @param param
	 * @return
	 */
	@PostMapping("/api/doorandled.xhtml")
	@ResponseBody
	public String doorandled(@RequestBody String param) {
		System.out.println(param);
		GatewayRunLog gatewayRunLog = JsonUtil.deserialize(param, GatewayRunLog.class);
		gatewayRunLog.setUuid(UUID.randomUUID().toString());
		System.out.println(gatewayRunLog.getCustom_id());
		if (gatewayRunLog.getCustom_id() != null) {
			if (gatewayRunLog.getDevice_serialno() != null) {
				DeviceController deviceController = new DeviceController();
				deviceController.setIdentified_no(gatewayRunLog.getDevice_serialno());
				deviceController = daoService.getObjectByUkey(DeviceController.class, "identified_no",
						deviceController.getIdentified_no());

				if (gatewayRunLog.getGate_serialno() != null) {
					DeviceGateway deviceGateway = new DeviceGateway();
					deviceGateway.setIdentified_no(gatewayRunLog.getGate_serialno());
					deviceGateway = daoService.getObjectByUkey(DeviceGateway.class, "identified_no",
							deviceGateway.getIdentified_no());

					if (gatewayRunLog.getDoor_lock() != null) {
					}
					if (gatewayRunLog.getLed() != null) {
					}

					daoService.saveObject(gatewayRunLog);
				}
			}
		}
		return "";
	}

	@PostMapping("/api/device/info.xhtml")
	@ResponseBody
	public String info(@RequestBody byte[] param) {
		return "";
	}

	@PostMapping("/api/device/register.xhtml")
	@ResponseBody
	public String register(@RequestBody String param) {
		DeviceController deviceController = JsonUtil.deserialize(param, DeviceController.class);
		try {
			String result = deviceControllerService.saveDeviceController(deviceController);
			return "{\"message\":\"" + result + "\"}";
		} catch (Exception e) {
			return "{\"error\":\"异常错误\"}";
		}
	}

	public static void main(String[] args) {
		List<HashMap<String, String>> sku = new ArrayList<HashMap<String, String>>();
		HashMap<String, String> mapsku = null;

		mapsku = new HashMap<String, String>();
		mapsku.put("url", "");
		mapsku.put("id", "");
		mapsku.put("change", "-2000");
		mapsku.put("price", "100");
		mapsku.put("price_type", "weight");
		mapsku.put("name", "80#苹果");
		sku.add(mapsku);

		StringBuffer url = new StringBuffer("http://localhost:8080/service/");
		url.append("SmallProgramService.do?method=creatOrder");
		url.append("&action=SHOPPING_RESULT");

		HashMap<String, Object> responseBodyMap = new HashMap<String, Object>();
		responseBodyMap.put("fridge_id", "567896565f48");
		responseBodyMap.put("user_id", 29);
		responseBodyMap.put("skus", sku);
		responseBodyMap.put("code", "SUCCESS");

		HttpResponse respone = HttpUtil.executePostMethod(url.toString(), JsonUtil.serialize(responseBodyMap), "utf-8");
		HttpEntity httpEntity = respone.getEntity();
		try {
			InputStream in = httpEntity.getContent();
			BufferedReader sf = new BufferedReader(new InputStreamReader(in));
			StringBuffer sb = new StringBuffer("");
			String s;
			while ((s = sf.readLine()) != null) {
				sb.append(s);
			}
			if (StringUtils.isNotBlank(sb)) {
				HashMap retrurnInfo = JsonUtil.deserialize(sb.toString(), HashMap.class);
				if ("SUCCESS".equals(retrurnInfo.get("code").toString())) {
					System.out.println(retrurnInfo.get("out_trade_no").toString());
				}
			}
		} catch (UnsupportedOperationException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}